const UsersRepository = require('../repositories/usersRepositories')
const OrderpayRepository = require("../repositories/orderpayRepositories");
const OrdercqRepositiories = require("../repositories/ordercqRepositories")
const CabinetRespositories = require("../repositories/cabinetRepositories")
const { formatDateTime, getTimeDifference } = require('../utils/dateFormat')
const MessageRepositories = require("../repositories/messageRepositories")
const EmailServices = require("./emailServices.js");
const bcrypt = require('bcrypt');
const config = require('../config') // 引入配置文件提取密钥
const SECRET_KEY = config.jwtSecret // 从配置文件中获取密钥
const jwt = require('jsonwebtoken');
const getlocTime = require('../utils/getLocalDateTime');


class UsersServices {
  // 提取通用的响应处理函数
  handleResponse(data, error, notFoundMessage = "用户未注册") {
    if (error) {
      return {
        code: 1,
        msg: error.message,
        statusCode: error.statusCode || 500,
      };
    }
    if (!data) {
      return {
        code: 1,
        msg: notFoundMessage,
      };
    }
    return {
      code: 0,
      data: data, // 返回数据
    };
  }

  /**
   * 用户登录
   * @param {string} account - 用户账号
   * @param {string} password - 用户密码
   * @returns {Promise<Object>} - 返回响应对象
   */
  async login(account, password) {
    try {
      // 检查参数是否为空
      if (!account || !password) {
        return {
          code: 1,
          msg: "账号和密码不能为空",
          statusCode: 400,
        };
      }

      // 检查账号和密码的长度是否大于 6
      if (account.length < 6 || password.length < 6) {
        return {
          code: 1,
          msg: "格式错误：账号和密码长度必须大于 6",
          statusCode: 400,
        };
      }

      // 查询用户
      const user = await UsersRepository.getUserByAccount(account);
      if (!user) {
        return {
          code: 1,
          msg: "用户不存在,请注册！",
          statusCode: 404,
        };
      }

      // 检查数据库中是否有密码
      if (!user.password) {
        return {
          code: 1,
          msg: "用户密码缺失，请联系管理员",
          statusCode: 500,
        };
      }

      // 验证密码
      const isPasswordValid = await bcrypt.compare(password, user.password);
      if (!isPasswordValid) {
        return {
          code: 1,
          msg: "密码错误",
        };
      }

      // 生成 JWT Token
      const token = jwt.sign(
        { id: user.id, account: user.account }, // 载荷
        SECRET_KEY, // 密钥
        { expiresIn: "1h" } // 过期时间
      );

      // 返回登录成功信息（不包含 Token）
      return {
        code: 0,
        data: {
          token,
          user: {
            id: user.id,
            nickname: user.nickname,
            account: user.account,
            avatar: user.avatar,
            state: user.state,
            money: user.money,
            email: user.email,
            tel: user.tel,
            xuexiao: user.xuexiao,
            xueyuan: user.xueyuan,
            zhuanye: user.zhuanye,
            xuehao: user.xuehao,
            banreason: user.banreason,
            registerTime: formatDateTime(user.createdAt),
            duration: getTimeDifference(user.createdAt),
          },
        },
      };
    } catch (error) {
      return {
        code: 1,
        msg: "登录失败",
        statusCode: 500,
        error: error.message,
      };
    }
  }

  /**
   * 注册新用户
   * @param {Object} userData - 用户数据
   * @returns {Promise<Object>} - 返回响应对象
   */
  async addNewUser(userData) {
    try {
      // 查询用户
      const { account } = userData;
      const user = await UsersRepository.getUserByAccount(account);
      if (user) {
        return {
          code: 1,
          msg: "用户已经存在,请更换账号后重试！",
          statusCode: 404,
        };
      }
      const { password, ...rest } = userData;

      // 检查密码是否为空
      if (!password) {
        return {
          code: 1,
          msg: "密码不能为空",
          statusCode: 400,
        };
      }

      // 加密密码
      const salt = await bcrypt.genSalt(10); // 生成盐
      const hashedPassword = await bcrypt.hash(password, salt); // 加密密码

      const currentTime = new Date();
      const newUserData = {
        ...rest,
        password: hashedPassword, // 添加加密后的密码
        createdAt: currentTime,
        updatedAt: currentTime,
      };

      // 创建用户
      const newUser = await UsersRepository.addNewUser(newUserData);

      // 移除敏感字段
      const userResponse = { ...newUser.get({ plain: true }) };
      delete userResponse.password; // 移除 password 字段

      return {
        code: 0,
        data: userResponse,
      };
    } catch (error) {
      return {
        code: 1,
        msg: "注册失败",
        statusCode: 500,
        error: error.message,
      };
    }
  }

  async delUserById(id) {
    try {
      const result = await UsersRepository.delUserById(id);
      return result
        ? this.handleResponse("用户注销成功")
        : this.handleResponse(null, null, "用户未注册");
    } catch (error) {
      return this.handleResponse(null, error);
    }
  }

  async updateUserById(id, userData) {
    try {
      // 自动更新 updatedAt 字段
      const updatedUserData = {
        ...userData,
        updatedAt: getlocTime(),
      };

      const result = await UsersRepository.updateUserById(id, updatedUserData);
      return result
        ? this.handleResponse("用户更新成功")
        : this.handleResponse(null, null, "用户不存在");
    } catch (error) {
      error.statusCode = 400; // 设置状态码
      return this.handleResponse(null, error);
    }
  }

  async getAllUsers() {
    try {
      const users = await UsersRepository.getAllUsers();
      return this.handleResponse(users);
    } catch (error) {
      return this.handleResponse(null, error);
    }
  }

  async getUserById(id) {
    try {
      const user = await UsersRepository.getUserById(id);
      return this.handleResponse(user);
    } catch (error) {
      return this.handleResponse(null, error);
    }
  }

  async getUserByAccount(account) {
    try {
      const user = await UsersRepository.getUserByAccount(account);
      return this.handleResponse(user);
    } catch (error) {
      return this.handleResponse(null, error);
    }
  }

  async uploadAvatar(id, avatarUrl) {
    const boolean = await UsersRepository.uploadAvatar(id, avatarUrl);
    return boolean
      ? this.handleResponse("更新成功", null, null)
      : this.handleResponse("更新失败", null, null);
  }

  async getPayQRCode() {
    try {
      const interfaces = require("os").networkInterfaces();
      console.log("interfaces: ");
      console.log(interfaces);

      // 直接定位到 WLAN 接口
      const wlanInterfaces = interfaces.WLAN || [];
      let jvYuWangIP = "没找到";

      // 遍历 WLAN 接口的所有地址
      for (const iface of wlanInterfaces) {
        if (iface.family === "IPv4" && !iface.internal) {
          jvYuWangIP = iface.address;
          break;
        }
      }

      if (jvYuWangIP === "没找到") {
        console.warn("未找到 WLAN 接口的 IPv4 地址");
        return this.handleResponse("未找到 WLAN 接口的 IPv4 地址");
      }

      console.log("返回的局域网 IP: ");
      console.log(jvYuWangIP);
      return this.handleResponse(`http://${jvYuWangIP}:8080/pay`);
    } catch (error) {
      console.log("error: ");
      console.log(error);
    }
  }
  /* 封禁用户 */
  async banUser(id, banreason) {
    const boolean = await UsersRepository.banUser(id, banreason);
    return boolean
      ? this.handleResponse(`id:${id}已被封禁`)
      : this.handleResponse(null, null, "封禁失败");
  }
  /* 模糊查询 */
  async getUserByAccMH(account) {
    const user = await UsersRepository.getUserByAccMH(account);
    return this.handleResponse(user);
  }
  /* 解封用户 */
  async releaseUser(id) {
    const boolean = await UsersRepository.releaseUser(id);
    return boolean
      ? this.handleResponse(`id:${id}已被解封`)
      : this.handleResponse(null, null, "解封失败");
  }
  /* 管理员根据ID获取用户全部信息 */
  async getUserByIdPlus(id) {
    try {
      const user = await UsersRepository.getUserByIdPlus(id);
      return this.handleResponse(user);
    } catch (error) {
      return this.handleResponse(null, error);
    }
  }
  /* 更新用户详细信息 */
  async updateUserDetailsById(id, newData) {
    const boolean = await UsersRepository.updateUserDetailsById(id, newData);
    return boolean
      ? this.handleResponse(`更新成功`)
      : this.handleResponse(null, null, "更新失败");
  }
  /* 修改密码 */
  async resetPwdById(id, form) {
    const { oldPassword, newPassword, confirmPassword } = form;
    /* 表单校验 */
    if (newPassword !== confirmPassword)
      return this.handleResponse(null, null, "两次输入的密码不一致");
    const user = await UsersRepository.getUserPwdById(id);
    const isPasswordValid = await bcrypt.compare(oldPassword, user.password);
    if (!isPasswordValid) {
      return this.handleResponse(null, null, "密码错误");
    }
    const salt = await bcrypt.genSalt(10); // 生成盐
    const hashedPassword = await bcrypt.hash(newPassword, salt); // 加密密码
    const boolean = await UsersRepository.resetPwdById(id, hashedPassword);
    return boolean
      ? this.handleResponse(`更新成功`)
      : this.handleResponse(null, null, "更新失败");
  }
  /* 充值接口 */
  async updateMoneyById(userId, amount, orderNum) {
    const orderData = {
      orderNum,
      user_id: userId,
      type: "充值",
      amount,
      des: `充值 ${amount} 元`,
    };
    const result = await OrderpayRepository.addNewOrder(orderData);
    const boolean = await UsersRepository.updateMoneyById(userId, amount);
    return boolean && result
      ? this.handleResponse(`充值成功`)
      : this.handleResponse(null, null, "充值失败");
  }
  /* 提现接口 */
  async tiXian(id, amount, orderNum) {
    const orderData = {
      orderNum,
      user_id: id,
      type: "提现",
      amount,
      des: `提现 ${amount} 元`,
    };
    const result = await OrderpayRepository.addNewOrder(orderData);
    const boolean = await UsersRepository.tiXian(id, amount);
    return boolean && result
      ? this.handleResponse(`提现成功`)
      : this.handleResponse(null, null, "提现失败,余额不足");
  }
  /* 存件接口 */
  async cunJian(cunId, quId, cabinetNum, cabinetBelong) {
    try {
      // 获取当前日期时间
      const now = new Date();
      const formatter = new Intl.DateTimeFormat("zh-CN", {
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
        hour12: false, // 使用 24 小时制
      });
      const currentTime = formatter
        .format(now)
        .replace(",", "")
        .replace("/", "-")
        .replace("/", "-");
      // 生成取件码
      const quCode = Math.floor(Math.random() * 900000) + 100000;
      /* @ToDo 调用物联网云平台api开门 */
      const cabinet = await CabinetRespositories.getCabinetByBelongAndNum(
        cabinetBelong,
        cabinetNum
      );
      const user = await UsersRepository.getUserByIdPlus(cunId)
      cabinet.isclosed = '0' // 开门
      cabinet.state = '1' // 占用
      cabinet.quCode = quCode; //设置取件码
      cabinet.usedtime = currentTime
      cabinet.usedaccount = user.account
      cabinet.updatedAt = currentTime
      await cabinet.save(); // 保存状态更新
      /* 生成订单 */
      const ordercqData = {
        orderNum: `ZGT${Date.now()}`,
        cabinetNum,
        cunId,
        quId,
        createdAt: currentTime,
        updatedAt: currentTime,
        cabinetBelong,
        quCode
      };
      const newOrdercq = await OrdercqRepositiories.addNewOrdercq(ordercqData);
      /* 发送站内信 */
      const msgData = {
        title: '待取通知',
        content: `您有一个新快件代取-${cabinetBelong}${cabinetNum}号柜, 取件码:${quCode}`,
        sendId: 10,
        acceptId: quId,
        idRead: 'no',
        isSystem: 'yes',
        createdAt: currentTime
      }
      EmailServices.sendEmail(
        "2727355098@qq.com",
        `您有一个新快件代取-${cabinetBelong}${cabinetNum}号柜, 取件码:${quCode}`
      );
      const newMessage = await MessageRepositories.addNewMsg(msgData);
      if (newOrdercq !== null && newMessage !== null)
        return this.handleResponse("存件成功,柜门已打开");
      else
        return this.handleResponse(null,"存件失败", null);
    } catch (error) {
      return this.handleResponse(null, error, null)
    }
  }
  /* 取件 */
  async quJian(quCode) {
    try {
      // 获取当前日期时间
      const now = new Date();
      const formatter = new Intl.DateTimeFormat("zh-CN", {
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
        hour12: false, // 使用 24 小时制
      });
      const currentTime = formatter
        .format(now)
        .replace(",", "")
        .replace("/", "-")
        .replace("/", "-");
      const cabinet = await CabinetRespositories.getCabinetByQucode(quCode);
      if (!cabinet)
        return this.handleResponse(null, "取件码错误", null);
      // 取件码正确
      /* @ToDo 调用api让硬件开门 */
      // 修改 相应快递柜的信息
      cabinet.isclosed = "0";
      cabinet.state = "0";
      cabinet.quCode = "000000";
      cabinet.usedtime = currentTime;
      cabinet.usedaccount = "jiangnanyun";
      cabinet.updatedAt = currentTime;
      await cabinet.save();
      // 根据 取件码 设置对应的订单状态为 已取
      const ordercq = await OrdercqRepositiories.getOrdercqByQucode(quCode);
      ordercq.state = "已取";
      ordercq.updatedAt = currentTime
      await ordercq.save();
      // 发送 快件被取 的站内信
      const msgData = {
        title: "取件成功",
        content: `您位于-${ordercq.cabinetBelong}${ordercq.cabinetNum}号柜的快递已成功取出,非本人操作请及时联系管理员`,
        sendId: 10,
        acceptId: ordercq.quId,
        idRead: "no",
        isSystem: "yes",
        createdAt: currentTime,
      };
      EmailServices.sendEmail(
        "2727355098@qq.com",
        `您位于-${ordercq.cabinetBelong}${ordercq.cabinetNum}号柜的快递已成功取出,非本人操作请及时联系管理员`
      );
      const newMessage = await MessageRepositories.addNewMsg(msgData);
      if (newMessage !== null) return this.handleResponse(`${ordercq.cabinetNum}号柜门已打开,请取件!`);
      else return this.handleResponse(null, "取件失败", null)
    } catch (error) {
      return this.handleResponse(null,error, null);
    }
    
  }
  
  /* @ToDo 让云平台调用关门接口 */
}

module.exports = new UsersServices()